package com.ihunanren.biz.weixin;

import static com.google.common.base.Preconditions.checkNotNull;

import java.io.InputStream;

import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;

import org.w3c.dom.Document;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;

import com.google.common.base.Throwables;
import com.ihunanren.biz.weixin.domain.WeixinEventMsg;
import com.ihunanren.biz.weixin.domain.WeixinEventType;
import com.ihunanren.biz.weixin.domain.WeixinImageMsg;
import com.ihunanren.biz.weixin.domain.WeixinLinkMsg;
import com.ihunanren.biz.weixin.domain.WeixinLocationMsg;
import com.ihunanren.biz.weixin.domain.WeixinMsg;
import com.ihunanren.biz.weixin.domain.WeixinTextMsg;
import com.ihunanren.common.Pair;
import com.ihunanren.dao.WeixinMsgType;

/**
 * @author kalman03
 */
public class WeixinXmlParser {

	public static Pair<? extends WeixinMsg, WeixinMsgType> toWeixinMsg(InputStream inputStream){
		checkNotNull(inputStream);
		try {
			DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance(); 
			DocumentBuilder db = dbf.newDocumentBuilder(); 
			Document document = db.parse(inputStream);
			
			NodeList nodeList =  document.getChildNodes().item(0).getChildNodes();
			
			WeixinMsgType msgType = getType(nodeList);
			
			if(msgType ==WeixinMsgType.TEXT){
				return new Pair<WeixinTextMsg, WeixinMsgType>(createWeixinTextMsg(nodeList), WeixinMsgType.TEXT);
			}else if(msgType ==WeixinMsgType.IMAGE){
				return new Pair<WeixinImageMsg, WeixinMsgType>(createWeixinImageMsg(nodeList), WeixinMsgType.IMAGE);
			}else if(msgType ==WeixinMsgType.LOCATION){
				return new Pair<WeixinLocationMsg, WeixinMsgType>(createWeixinLocationMsg(nodeList), WeixinMsgType.LOCATION);
			}else if(msgType ==WeixinMsgType.LINK){
				return new Pair<WeixinLinkMsg, WeixinMsgType>(createWeixinLinkMsg(nodeList), WeixinMsgType.LINK);
			}else if(msgType ==WeixinMsgType.EVENT){
				return new Pair<WeixinEventMsg, WeixinMsgType>(createWeixinEventMsg(nodeList), WeixinMsgType.EVENT);
			}
		} catch (Exception e) {
			Throwables.propagate(e);
		}
		return null;
	}
	
	private static WeixinTextMsg createWeixinTextMsg(NodeList nodeList){
		WeixinTextMsg textMsg = new WeixinTextMsg();
		for(int i=0;i<nodeList.getLength();i++){
			Node node = nodeList.item(i);
			String name = node.getNodeName();
			String value = node.getTextContent();
			if("ToUserName".equals(name)){
				textMsg.setToUserName(value);
			}else if("FromUserName".equals(name)){
				textMsg.setFromUserName(value);
			}else if("CreateTime".equals(name)){
				textMsg.setCreateTime(Long.parseLong(value));
			}else if("Content".equals(name)){
				textMsg.setContent(value);
			}else if("MsgId".equals(name)){
				textMsg.setMsgId(Long.parseLong(value));
			}
		}
		textMsg.setMsgType(WeixinMsgType.TEXT.getValue());
		return textMsg;
	}
	
	private static WeixinImageMsg createWeixinImageMsg(NodeList nodeList){
		WeixinImageMsg imageMsg = new WeixinImageMsg();
		for(int i=0;i<nodeList.getLength();i++){
			Node node = nodeList.item(i);
			String name = node.getNodeName();
			String value = node.getTextContent();
			if("ToUserName".equals(name)){
				imageMsg.setToUserName(value);
			}else if("FromUserName".equals(name)){
				imageMsg.setFromUserName(value);
			}else if("CreateTime".equals(name)){
				imageMsg.setCreateTime(Long.parseLong(value));
			}else if("PicUrl".equals(name)){
				imageMsg.setPicUrl(value);
			}else if("MsgId".equals(name)){
				imageMsg.setMsgId(Long.parseLong(value));
			}
		}
		imageMsg.setMsgType(WeixinMsgType.IMAGE.getValue());
		return imageMsg;
	}
	
	private static WeixinLocationMsg createWeixinLocationMsg(NodeList nodeList){
		WeixinLocationMsg locationMsg = new WeixinLocationMsg();
		for(int i=0;i<nodeList.getLength();i++){
			Node node = nodeList.item(i);
			String name = node.getNodeName();
			String value = node.getTextContent();
			if("ToUserName".equals(name)){
				locationMsg.setToUserName(value);
			}else if("FromUserName".equals(name)){
				locationMsg.setFromUserName(value);
			}else if("CreateTime".equals(name)){
				locationMsg.setCreateTime(Long.parseLong(value));
			}else if("Location_X".equals(name)){
				locationMsg.setLocation_x(value);
			}else if("Location_Y".equals(name)){
				locationMsg.setLocation_y(value);
			}else if("Scale".equals(name)){
				locationMsg.setScale(Integer.parseInt(value));
			}else if("Label".equals(name)){
				locationMsg.setLabel(value);
			}else if("MsgId".equals(name)){
				locationMsg.setMsgId(Long.parseLong(value));
			}
		}
		locationMsg.setMsgType(WeixinMsgType.LOCATION.getValue());
		return locationMsg;
	}
	
	private static WeixinLinkMsg createWeixinLinkMsg(NodeList nodeList){
		WeixinLinkMsg linkMsg = new WeixinLinkMsg();
		for(int i=0;i<nodeList.getLength();i++){
			Node node = nodeList.item(i);
			String name = node.getNodeName();
			String value = node.getTextContent();
			if("ToUserName".equals(name)){
				linkMsg.setToUserName(value);
			}else if("FromUserName".equals(name)){
				linkMsg.setFromUserName(value);
			}else if("CreateTime".equals(name)){
				linkMsg.setCreateTime(Long.parseLong(value));
			}else if("Title".equals(name)){
				linkMsg.setTitle(value);
			}else if("Description".equals(name)){
				linkMsg.setDescription(value);
			}else if("Url".equals(name)){
				linkMsg.setUrl(value);
			}else if("MsgId".equals(name)){
				linkMsg.setMsgId(Long.parseLong(value));
			}
		}
		linkMsg.setMsgType(WeixinMsgType.TEXT.getValue());
		return linkMsg;
	}
	
	private static WeixinEventMsg createWeixinEventMsg(NodeList nodeList) {
		WeixinEventMsg eventMsg = new WeixinEventMsg();
		for (int i = 0; i < nodeList.getLength(); i++) {
			Node node = nodeList.item(i);
			String name = node.getNodeName();
			String value = node.getTextContent();
			if ("ToUserName".equals(name)) {
				eventMsg.setToUserName(value);
			} else if ("FromUserName".equals(name)) {
				eventMsg.setFromUserName(value);
			} else if ("CreateTime".equals(name)) {
				eventMsg.setCreateTime(Long.parseLong(value));
			} else if ("Event".equals(name)) {
				eventMsg.setEventType(WeixinEventType.getType(value));
			} else if ("EventKey".equals(name)) {
				eventMsg.setEventKey(value);
			}
		}
		eventMsg.setMsgType(WeixinMsgType.EVENT.getValue());
		return eventMsg;
	}
	
	private static WeixinMsgType getType(NodeList nodeList){
		for(int i=0;i<nodeList.getLength();i++){
			Node node = nodeList.item(i);
			String name = node.getNodeName();
			if("MsgType".equals(name)){
				WeixinMsgType type = WeixinMsgType.get(node.getTextContent());
				if(type != null)return type;
			}
		}
		return null;
	}
}
